/****************************************************************************
 *
 * Copyright (C) 2003-2008 Los Alamos National Security, LLC
 *                         Packet Analytics Corporation
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License Version 2 as
 * published by the Free Software Foundation.  You may not use, modify or
 * distribute this program under any other version of the GNU General
 * Public License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 *
 ****************************************************************************/
package nfse.gui.client;

//JAVA Packages
import java.util.*;

//NFSE Packages
import nfse.gui.client.data.*;
import nfse.gui.client.reports.TopValues;
import nfse.gui.query.QueryInfo;
import nfse.gui.query.QueryOptions;
import nfse.gui.query.QueryResult;
import nfse.gui.query.TypeInfo;
import nfse.gui.record.FlexRecord;
import nfse.gui.record.FlexRecordField;
import nfse.gui.record.FlexRecordGroup;
import nfse.gui.util.NetUtil;
import nfse.gui.client.reports.*;
import com.gwtext.client.widgets.layout.*;

//GWTEXT Packages
import com.gwtext.client.core.EventObject;
import com.gwtext.client.core.Position;
import com.gwtext.client.widgets.Panel;
import com.gwtext.client.data.*;
import com.gwtext.client.widgets.*;
import com.gwtext.client.widgets.grid.*;
import com.gwtext.client.widgets.form.*;
import com.gwtext.client.widgets.Button;
import com.gwtext.client.widgets.MessageBox;
import com.gwtext.client.widgets.MessageBoxConfig;
import com.gwtext.client.widgets.event.ButtonListenerAdapter;
import com.gwtext.client.widgets.grid.ColumnConfig;
import com.gwtext.client.widgets.grid.ColumnModel;
import com.gwtext.client.widgets.grid.event.*;
import com.gwtext.client.widgets.layout.VerticalLayout;

//GWT Packages
import com.google.gwt.user.client.rpc.*;
import com.google.gwt.core.client.*;

/**
 * Current Issues
 * 
 * 1. Delete does not work. Delete button is active but delete function is not.
 * 2008-07-05 2. Partial Result Set Display: Not sure if this is working right
 * now. In any case need to be able to display a patial set 2008-07-05 3.
 * Handling multiple types in a query has not been tested yet. I believe it
 * works but I need data 2008-07-05
 * 
 * 
 * @author john
 * 
 */

public class AnalysisPanel extends Panel {

    boolean resultsDisplayed = false;

    NetFSEClient client = null;

    SearchAnalysisTab searchAnalysisTab;

    private final int[] TYPE_SUMMARY_FIELD_SEQ = { NetFSEClient.FIELD_SRC_IP, NetFSEClient.FIELD_DST_IP,
            NetFSEClient.FIELD_DST_PORT, NetFSEClient.FIELD_PROTOCOL };

    private HashMap nextFieldInSeq = new HashMap();

    private HashMap gridPanelMap = new HashMap();

    private HashMap resultsPanelMap = new HashMap();

    private HashMap summaryPanelMap = new HashMap();

    private HashMap summaryPanelMap2 = new HashMap();

    private HashMap analysisOptionsDialogMap = new HashMap();

    private boolean[] active = new boolean[0];

    private int[] n = new int[0];

    private int[] offsets = new int[0];

    private AnalysisOptionsDialog[] optionDialogs2 = new AnalysisOptionsDialog[0];

    private String[] orderBy = new String[0];

    private String queryId = null;

    private int[] recordCounts = new int[0];

    private String[] schemas = new String[0];

    private int[] typeIdxs = new int[0];

    private String[] typeNames = new String[0];

    private int[] types = new int[0];

    private String[] where = new String[0];

    private int panelWidth = 950;

    private int[] localTypes;

    int resultQueryCountTotal = 0;

    private int numOfTypes = 0;

    public TypeInfo typeInfo;

    // int[] resultGridColumnWidth = { 150, 150, 150, 50, 50, 50, 150, 50, 50 };

    int[] resultSummaryGridColumnWidth = { 150, 100, 50, 50, 65, 65 };

    public QueryResult queryResultSet = null;

    private QueryInfo queryInfo = null;

    public Label statusLabel = new Label("Query Status: ");

    public AnalysisPanel(NetFSEClient client, String queryId, SearchAnalysisTab searchAnalysisTab) {
        this.setTitle(queryId);
        // this.setWidth(panelWidth);
        // this.setAutoWidth(true); Does not do a thing. Useless for setting the
        // width when a component is added
        this.setAutoScroll(true);
        this.setClosable(false);
        this.client = client;
        this.queryId = queryId;
        this.searchAnalysisTab = searchAnalysisTab;
        this.typeInfo = client.typeInfo;
        setTypes(typeInfo);
        numOfTypes = typeInfo.getNumTypes();
        this.setLayout(new VerticalLayout(15));
    }

    public AnalysisPanel(NetFSEClient client, String queryId, SearchAnalysisTab searchAnalysisTab, int[] localTypes) {
        this.setTitle(queryId);
        this.client = client;
        this.queryId = queryId;
        this.searchAnalysisTab = searchAnalysisTab;
        this.typeInfo = client.typeInfo;
        this.localTypes = localTypes;
        setTypes(typeInfo);

        numOfTypes = localTypes.length;
        this.setLayout(new VerticalLayout(15));
        // deleteDialog = new DeleteDialogBox();
        // deleteDialog.addPopupListener(this);

    }

    // This is currently not called until I get the display of a single type
    // results and type summary. After that works then multiple types can be
    // tested
    // This is called every time a rpc call is complete to see if the main panel
    // is ready to be built. The main panel will only be built when the page is
    // loaded
    public synchronized void addAllPanelsIntoMainPanel() {
        if (resultsDisplayed)
            return;

        if ((summaryPanelMap2.size() == queryInfo.types.length) && (gridPanelMap.size() == queryInfo.types.length)) {
            // Build the main panel with all the type grids and type summary
            // panels
            if (this.getComponents().length != 2 * queryInfo.types.length) {
                for (int x = 0; x < queryInfo.types.length; x++) {
                    this.add((Panel) resultsPanelMap.get(queryInfo.types[x] + ""));
                    this.add((Panel) summaryPanelMap2.get(queryInfo.types[x] + ""));
                }
                client.analysisPanelGroup.addPanelToTab(this);
                resultsDisplayed = true;
            }

        }

    }

    /*
     * Called from getTypeResults which gets the db results for a specified type
     */
    public void buildResultsGridPanel(FlexRecordGroup frg) {
        Panel resultsGridPanel = new Panel();
        // resultsGridPanel.setWidth(panelWidth);
        String name = client.getTypeName(frg.typeID);
        resultsGridPanel.setTitle(name);
        Toolbar toolBar = new Toolbar();

        final int localType = frg.typeID;
        final ToolbarTextItem pageStatus = new ToolbarTextItem("");

        final ToolbarButton hideGridBtn = new ToolbarButton("Hide Grid");
        ToolbarButton deleteBtn = new ToolbarButton("Delete");
        ToolbarButton exportBtn = new ToolbarButton("Export");
        ToolbarButton optionsBtn = new ToolbarButton("Options");

        hideGridBtn.addListener(new ButtonListenerAdapter() {
            public void onClick(Button button, EventObject e) {
                if (button.getText().equals("Hide Grid")) {
                    hideGridBtn.setText("Show Grid");
                    Panel localPanel = (Panel) gridPanelMap.get(localType + "");
                    localPanel.hide();
                } else {
                    hideGridBtn.setText("Hide Grid");
                    Panel localPanel = (Panel) gridPanelMap.get(localType + "");
                    localPanel.show();
                }
            }
        });
        toolBar.addButton(hideGridBtn);

        deleteBtn.addListener(new ButtonListenerAdapter() {
            public void onClick(Button button, EventObject e) {
                MessageBox.show(new MessageBoxConfig() {
                    {
                        setMsg("Enter an SQL delete statement omitting the 'delete':");
                        setWidth(300);
                        setButtons(MessageBox.OKCANCEL);
                        setMultiline(true);
                        setCallback(new MessageBox.PromptCallback() {
                            public void execute(String btnID, String text) {
                                if (btnID.equals("ok")) {
                                    // delete(getQueryID(), type, text);
                                }
                            }
                        });
                    }
                });
            }

        });
        toolBar.addButton(deleteBtn);
        exportBtn.addListener(new ButtonListenerAdapter() {
            public void onClick(Button button, EventObject e) {
                System.out.println("help");
                Panel activePanel = client.analysisPanelGroup.tabPanel.getActiveTab();
                String queryId = activePanel.getTitle();

                String url = "export?queryid=" + queryId + "&type=" + localType + "&where="
                        + NetUtil.convertToHex(getWhere(localType)) + "&orderby=" + getOrderBy(localType);
                System.out.println(url);
                Window w = new Window();
                w.setTitle("Export");
                w.load(url);
                w.show();
                // Window.open(url, "Export", "");
            }
        });
        toolBar.addButton(exportBtn);

        final AnalysisPanelOptionsDialog optDialog = new AnalysisPanelOptionsDialog(this, localType, client
                .getTypeName(localType), getSchema(localType));

        optionsBtn.addListener(new ButtonListenerAdapter() {
            public void onClick(Button button, EventObject e) {
                optDialog.show();
            }
        });
        toolBar.addButton(optionsBtn);
        toolBar.addItem(pageStatus);
        resultsGridPanel.add(toolBar);
        BaseGridPanel bgp = new BaseGridPanel(client, this, frg, resultQueryCountTotal);
        // bgp.setWidth(panelWidth);
        bgp.buildGrid(frg.typeName, frg.getColumnWidths());
        gridPanelMap.put(frg.typeID + "", bgp);
        resultsGridPanel.add(bgp);

        resultsPanelMap.put(frg.typeID + "", resultsGridPanel);

        // this.add(resultsGridPanel);
        // client.analysisPanelGroup.addPanelToTab(this);

    }

    public void createTypeSummaryPanel(int type, int summaryType, String typeName, TopValues topValues) {
        BaseGridPanel bgp = new BaseGridPanel(client, this, topValues, summaryType);
        bgp.setWidth(500);
        bgp.setHeight(280);
        bgp.buildGrid(client.getTypeName(type), resultSummaryGridColumnWidth);

        HashMap summaryPanels = (HashMap) summaryPanelMap.get(type + "");
        summaryPanels.put(summaryType + "", bgp);
        boolean summaryPanelsComplete = true;
        if (summaryPanels.size() != 4l) {
            summaryPanelsComplete = false;
        }

        if (summaryPanelsComplete) {
            Panel allSummaryPanel = new Panel();
            allSummaryPanel.setHeight(900);
            allSummaryPanel.setLayout(new VerticalLayout(0));

            Panel topPanel = new Panel();
            topPanel.setLayout(new HorizontalLayout(0));
            topPanel.add((Panel) summaryPanels.get(NetFSEClient.FIELD_DST_IP + ""));
            topPanel.add((Panel) summaryPanels.get(NetFSEClient.FIELD_SRC_IP + ""));
            allSummaryPanel.add(topPanel);

            Panel bottomPanel = new Panel();
            bottomPanel.setLayout(new HorizontalLayout(0));
            bottomPanel.add((Panel) summaryPanels.get(NetFSEClient.FIELD_DST_PORT + ""));
            bottomPanel.add((Panel) summaryPanels.get(NetFSEClient.FIELD_PROTOCOL + ""));
            allSummaryPanel.add(bottomPanel);

            summaryPanelMap2.put(type + "", buildSummaryPanel(type, typeName, allSummaryPanel));
            // this.add(buildSummaryPanel(type, typeName, allSummaryPanel));
            // client.analysisPanelGroup.addPanelToTab(this);
        }
    }

    public Panel buildSummaryPanel(int type, String typeName, Panel allSummaryPanels) {
        final Panel summaryPanel = new Panel();
        summaryPanel.setHeight(650);
        summaryPanel.setWidth(1000);
        summaryPanel.setTitle(typeName);
        final Panel localAllSummaryPanels = allSummaryPanels;
        final int localType = type;
        Toolbar toolBar = new Toolbar();
        final ToolbarTextItem pageStatus = new ToolbarTextItem("");
        final ToolbarButton hideGridBtn = new ToolbarButton("Hide Grids");
        ToolbarButton refreshBtn = new ToolbarButton("Refresh");
        hideGridBtn.addListener(new ButtonListenerAdapter() {
            public void onClick(Button button, EventObject e) {
                if (button.getText().equals("Hide Grids")) {
                    hideGridBtn.setText("Show Grids");
                    localAllSummaryPanels.hide();
                } else {
                    hideGridBtn.setText("Hide Grids");
                    localAllSummaryPanels.show();
                }
            }
        });
        toolBar.addButton(hideGridBtn);
        refreshBtn.addListener(new ButtonListenerAdapter() {
            public void onClick(Button button, EventObject e) {
                // optionDialogs2[typeIdx].show();
            }
        });

        toolBar.addButton(refreshBtn);
        toolBar.addItem(pageStatus);
        summaryPanel.add(toolBar);
        summaryPanel.add(allSummaryPanels);

        return summaryPanel;
    }

    public int[] getActiveTypes() {
        Vector idxs = new Vector();
        for (int i = 0; i < active.length; i++) {
            if (active[i]) {
                for (int x = 0; x < typeIdxs.length; x++) {
                    if (typeIdxs[x] == i) {
                        idxs.addElement(new Integer(types[i]));
                        break;
                    }
                }

            }
        }
        int[] temp = new int[idxs.size()];
        for (int i = 0; i < temp.length; i++) {
            temp[i] = ((Integer) idxs.elementAt(i)).intValue();
            // System.out.println("Active: " + temp[i]);
        }
        return temp;
    }

    private GridPanel getTypeGrid(int type) {
        return (GridPanel) gridPanelMap.get(type + "");
    }

    private void clearGrid(int type) {
        System.out.println("Called clearGrid()");
        GridPanel gp = new GridPanel();
        gridPanelMap.put(type + "", gp);

        resultsPanelMap.put(type + "", new Panel());
    }

    private void clearTable(int type) {
        // FlexTable table = getDataTable(type);
        //	        
        // setTableActive(type, false);
        // if (table != null)
        // while (table.getRowCount() > 1)
        // table.removeRow(1);
    }

    private void delete(int type, String sql) {

        final int tempType = type;
        final String tempQueryId = queryId;

        QueryServiceAsync NetFSEService = (QueryServiceAsync) GWT.create(QueryService.class);

        ServiceDefTarget endpoint = (ServiceDefTarget) NetFSEService;
        endpoint.setServiceEntryPoint(NetFSEClient.QUERY_URL);

        AsyncCallback callback = new AsyncCallback() {
            public void onFailure(Throwable caught) {
                NetFSEClient.redirect("NetFSEClient.html");
            }

            public void onSuccess(Object result) {
                getTypeResults(tempType, 0);
            }
        };

        NetFSEService.delete(queryId, type, sql, callback);

    }

    public int getRecordCount(int type) {
        return recordCounts[typeIdxs[type]];
    }

    public String getSchema(int type) {
        return schemas[typeIdxs[type]];
    }

    public void getTypeResults(int type, int offset) {

        if (offset > getRecordCount(type))
            offset = 0;

        final int userNavigatedToFirstPage = offset;
        if (offset == -5) {
            // offset = 0;
        }
        final int n = getN(type);
        final int tempType = type;
        final int tempTypeIdx = typeIdxs[type];
        final int tempOffset = offset;
        final int count = getRecordCount(type);
        QueryServiceAsync nfseService = (QueryServiceAsync) GWT.create(QueryService.class);

        ServiceDefTarget endpoint = (ServiceDefTarget) nfseService;
        endpoint.setServiceEntryPoint(NetFSEClient.QUERY_URL);

        AsyncCallback callback = new AsyncCallback() {

            public void onFailure(Throwable caught) {
                NetFSEClient.redirect("NetFSEClient.html");
                // clearTable(tempType);
            }

            public void onSuccess(Object result) {
                // statusLabels[tempTypeIdx].setText("Formatting data table;
                // please wait");

                QueryResult qr = (QueryResult) result;

                if (qr != null)
                    resultQueryCountTotal = qr.count;
                // *******************************
                // Query failed. No result set
                // *******************************
                if (qr == null) {
                    String where = getWhere(tempType);
                    String orderBy = getOrderBy(tempType);
                    String str1 = "";
                    String str2 = "";
                    String title = "";
                    if (where.length() == 0 && orderBy.length() > 0) {
                        title = "Error in Order By Clause";
                        str1 = "Order By";
                        str2 = "<hr>Order By: <br><pre>" + orderBy + "</pre>";
                    } else if (where.length() > 0 && orderBy.length() == 0) {
                        title = "Error in Where Clause";
                        str1 = "Where";
                        str2 = "<hr>Where: <br><pre>" + where + "</pre>";
                    } else {
                        title = "Error in Where or Order By Clause";
                        str1 = "Where or Order By";
                        str2 = "<hr>Where: <br><pre>" + where + "</pre><hr>Order By: <br><pre>" + orderBy + "</pre>";
                    }
                    String html = "An error was returned by the server indicating an error in the " + str1
                            + " clause.<br>" + str2;

                    MessageBox.alert(title, html);
                    // statusLabels[tempTypeIdx].setText("Error retrieving
                    // records. Check Where and Order By SQL in Options.");
                    System.out.println("The Results set is null");
                    clearGrid(tempType);
                    return;
                }

                setRecordCount(tempType, qr.count);

                setOffset(tempType, tempOffset);
                int first = tempOffset + 1;
                int last = tempOffset + n;
                if (last > qr.count)
                    last = qr.count;

                // Query succeeded but did not bring any results back
                if (qr.count == -1) {
                    clearGrid(tempType);
                    // statusLabels[tempTypeIdx].setText("Data type not
                    // specified in original search.");
                    hideTable(tempType);
                    System.out.println("Count is -1: " + tempType);
                }
                // else if (qr.count == 0)
                // {
                // //For testing purposes
                // testAnalysisPanel();
                // }
                else {
                    if (qr.flexRecordGroup.records.length > 0) {

                        // System.out.println("the userN is " +
                        // userNavigatedToFirstPage);
                        if ((tempOffset > 0) || (tempOffset == -1) || (userNavigatedToFirstPage == -5)) {
                            // Handle result when using sort column or getting
                            // another page from an existing query
                            addNextRecordSetToAnalysis(qr.flexRecordGroup, false);
                        } else if (tempOffset == -2) {
                            // Handle result from using Option Query
                            addNextRecordSetToAnalysis(qr.flexRecordGroup, true);
                        } else {
                            // Handle result from a new query
                            buildResultsGridPanel(qr.flexRecordGroup);
                        }
                    } else {
                        clearGrid(tempType);
                    }

                    // updateTable(tempType, getTypeGrid(tempType),
                    // getDataTable(tempType), qr);
                    String status = "";
                    if (qr.flexRecordGroup.records.length > 0) {
                        status = "Displaying records " + first + "-" + last + " of " + getRecordCount(tempType);
                        schemas[typeIdxs[tempType]] = qr.schema;
                    } else
                        status = "No matching records found.";
                    if (qr.qs.status != 1)
                        status += " (Search in progress)";
                    // statusLabels[tempTypeIdx].setText(status);

                }
                addAllPanelsIntoMainPanel();
            }
        };
        // statusLabels[tempTypeIdx].setText("Retrieving records from database;
        // please wait");
        String localWhere = getWhere(type);
        if (localWhere == null)
            localWhere = "";

        String localOrderBy = getOrderBy(type);
        if (localOrderBy == null)
            localOrderBy = "";
        nfseService.get(queryId, n, offset, type, localWhere, localOrderBy, callback);
    }

    public void addNextRecordSetToAnalysis(FlexRecordGroup frg, boolean reloadGridStatus) {
        BaseGridPanel brg = (BaseGridPanel) gridPanelMap.get(frg.typeID + "");
        brg.totalResultRecords = resultQueryCountTotal;
        brg.getRecords(frg);
        brg.addPageToTab();
        // This is only because the Options query does not get the record count,
        // current page, etc from the baseGridPanel
        if (reloadGridStatus) {
            brg.resetPagingToolbarStatusAfterNewQuery();
        }

        brg.setPagingToolBarStatus();
    }

    public void setQueryResult(QueryResult rs) {
        queryResultSet = rs;
    }

    public boolean getActive(int type) {
        return active[typeIdxs[type]];
    }

    public String[] getActiveWhere() {
        int[] types = getActiveTypes();
        String[] temp = new String[types.length];
        for (int i = 0; i < types.length; i++)
            temp[i] = getWhere(types[i]);
        return temp;
    }

    // private FlexTable getDataTable(int type) {
    // return dataTables[typeIdxs[type]];
    // }

    public int getN(int type) {
        return n[typeIdxs[type]];
    }

    public int getOffset(int type) {
        return offsets[typeIdxs[type]];
    }

    public String getOrderBy(int type) {
        return orderBy[typeIdxs[type]];
    }

    private void getTypeSummary(String queryId, int type, int field) {
        ReportServiceAsync nfseService = (ReportServiceAsync) GWT.create(ReportService.class);

        ServiceDefTarget endpoint = (ServiceDefTarget) nfseService;
        endpoint.setServiceEntryPoint(NetFSEClient.REPORT_URL);

        final String tempQueryID = queryId;
        final String fieldName = client.getFieldName(field);
        final int tempField = field;
        final int tempType = type;
        final int typeIdx = typeIdxs[type];
        final String tempTypeName = typeNames[typeIdxs[type]];
        // final boolean tempUpdateHeader = updateHeader;

        AsyncCallback callback = new AsyncCallback() {
            public void onFailure(Throwable caught) {
                NetFSEClient.redirect("NetFSEClient.html");
            }

            public void onSuccess(Object result) {

                TopValues topValues = (TopValues) result;

                if (topValues == null) {
                    System.out.println("The top values query is null for field " + tempField);
                    return;
                }

                // if (topValues.highs.length > 0) {
                createTypeSummaryPanel(tempType, tempField, tempTypeName, topValues);
                // }

                int nextField = ((Integer) nextFieldInSeq.get(tempType + "")).intValue();
                nextField++;
                nextFieldInSeq.put(tempType + "", new Integer(nextField));
                if (nextField == TYPE_SUMMARY_FIELD_SEQ.length) {
                    addAllPanelsIntoMainPanel();
                } else {
                    getTypeSummary(tempQueryID, tempType, TYPE_SUMMARY_FIELD_SEQ[nextField]);
                }

                // }
            }
        };
        // summaryStatusLabels[typeIdx].setText("Request in progress, please
        // wait.");
        String localWhere = getWhere(type);
        if (localWhere == null)
            localWhere = "";
        nfseService.getTopValues(queryId, type, field, 10, localWhere, callback);
    }

    public void setOffset(int type, int offset) {
        offsets[typeIdxs[type]] = offset;
    }

    public void setOrderBy(int type, String orderBy) {
        this.orderBy[typeIdxs[type]] = orderBy;
    }

    private String[] getWhere() {
        int[] types = client.getActiveTypes();
        String[] temp = new String[types.length];
        for (int i = 0; i < types.length; i++)
            temp[i] = getWhere(types[i]);
        return temp;
    }

    public String getWhere(int type) {
        return where[typeIdxs[type]];
    }

    private void hideSummary(int type) {
        GridPanel localGrid = (GridPanel) gridPanelMap.get(type + "");
        localGrid.hide();
    }

    private void hideTable(int type) {
        // FlexTable table = getTable(type);
        // table.setVisible(false);
    }

    public void updateOptions(int type, String where, String orderBy, int n) {
        int typeIdx = this.typeIdxs[type];
        this.where[typeIdx] = where;

        this.orderBy[typeIdx] = orderBy;
        this.n[typeIdx] = n;
        this.getTypeResults(type, -2);
    }

    // Gets the query info about this queryId including the subset of types
    // then calls setQuery with this queryInfo
    public void openQuery(String queryID) {
        final String tempQueryID = queryID;
        QueryServiceAsync nfseService = (QueryServiceAsync) GWT.create(QueryService.class);

        ServiceDefTarget endpoint = (ServiceDefTarget) nfseService;
        endpoint.setServiceEntryPoint(NetFSEClient.QUERY_URL);

        AsyncCallback callback = new AsyncCallback() {
            public void onFailure(Throwable caught) {
                NetFSEClient.redirect("NetFSEClient.html");
            }

            public void onSuccess(Object result) {
                QueryInfo info = (QueryInfo) result;
                if (info == null) {
                    NetFSEClient.showGenericDialog("Invalid Search ID", "The Search ID specified ('" + tempQueryID
                            + "') was invalid.");
                } else {
                    setQuery(tempQueryID, info);
                }
            }
        };

        nfseService.getQueryInfo(queryID.trim(), callback);
    }

    public void setAnalysisOptions(int type, String where, String orderBy, int n) {
        int typeIdx = this.typeIdxs[type];
        this.where[typeIdx] = where;

        this.orderBy[typeIdx] = orderBy;
        this.n[typeIdx] = n;
        this.getTypeResults(type, 0);
    }

    private void setQuery(String queryID, QueryInfo info) {
        this.resultsDisplayed = false;

        this.queryInfo = info;
        for (int i = 0; i < this.recordCounts.length; i++)
            recordCounts[i] = -1;

        for (int i = 0; i < types.length; i++) {
            this.where[i] = "";
            this.orderBy[i] = "";
            // this.optionDialogs2[i].reset();
            this.n[i] = 15; // page size

            for (int j = 0; j < info.types.length; j++) {
                if (info.types[j] == types[i]) {
                    getTypeResults(types[i], 0);
                    summary(queryId, types[i]);
                }
            }

        }

    }

    private void summary(String queryId, int type) {
        // summaryTables[typeIdxs[type]].setVisible(true);

        HashMap localSummaryPanels = new HashMap();
        summaryPanelMap.put(type + "", localSummaryPanels);

        nextFieldInSeq.put(type + "", new Integer(0));

        getTypeSummary(queryId, type, TYPE_SUMMARY_FIELD_SEQ[0]);
        // getTypeSummary(queryId, type, NetFSEClient.FIELD_SRC_IP, false);
        // getTypeSummary(queryId, type, NetFSEClient.FIELD_DST_PORT, false);
        // getTypeSummary(queryId, type, NetFSEClient.FIELD_PROTOCOL, false);
    }

    public void setRecordCount(int type, int offset) {
        recordCounts[typeIdxs[type]] = offset;
    }

    private void setTableActive(int type, boolean act) {
        this.active[typeIdxs[type]] = act;
    }

    /*
     * Called from initTypes method in NetFSEClient. Will not be called until
     * the end of NetFSEClient.onModuleLoad
     */
    public void setTypes(TypeInfo typeInfo) {

        this.typeInfo = typeInfo;

        int numTypes = typeInfo.getNumTypes();
        int maxType = -1;

        this.n = new int[numTypes];

        // this.optionDialogs = new BrowseOptionsDialogBox[numTypes];
        this.optionDialogs2 = new AnalysisOptionsDialog[numTypes];
        // this.statusLabels = new Label[numTypes];
        // this.summaryStatusLabels = new Label[numTypes];
        this.recordCounts = new int[numTypes];
        this.schemas = new String[numTypes];
        this.where = new String[numTypes];
        this.active = new boolean[numTypes];
        this.orderBy = new String[numTypes];
        this.types = new int[numTypes];
        this.typeIdxs = new int[numTypes];
        this.typeNames = new String[numTypes];
        this.offsets = new int[numTypes];
        this.recordCounts = new int[numTypes];

        int[] types = typeInfo.getTypes();
        for (int i = 0; i < numTypes; i++) {
            if (maxType < types[i])
                maxType = types[i];
        }

        this.typeIdxs = new int[maxType + 1];
        for (int i = 0; i < numTypes; i++) {
            final int type = types[i];
            final int typeIdx = i;

            //
            // showHideLinks[i] = new Hyperlink("Hide", "Hide" + type);
            // // showHideLinks[i].setText("Hide");
            // showHideLinks[i].addClickListener(new ClickListener() {
            // public void onClick(Widget sender) {
            // String value = showHideLinks[typeIdx].getText();
            // if (value.equals("Show")) {
            // showHideLinks[typeIdx].setText("Hide");
            // dataTables[typeIdx].setVisible(true);
            // } else {
            // showHideLinks[typeIdx].setText("Show");
            // dataTables[typeIdx].setVisible(false);
            // }
            // }
            // });
            //
            // showHideSummaryLinks[i] = new Hyperlink("Hide", "Hide" + type);
            // // showHideLinks[i].setText("Hide");
            // showHideSummaryLinks[i].addClickListener(new ClickListener() {
            // public void onClick(Widget sender) {
            // String value = showHideSummaryLinks[typeIdx].getText();
            // if (value.equals("Show")) {
            // showHideSummaryLinks[typeIdx].setText("Hide");
            // summaryDataTables[typeIdx].setVisible(true);
            // } else {
            // showHideSummaryLinks[typeIdx].setText("Show");
            // summaryDataTables[typeIdx].setVisible(false);
            // }
            // }
            // });
            //
            // dataTables[i] = new FlexTable();
            // summaryDataTables[i] = new FlexTable();
            typeIdxs[type] = i;

            recordCounts[i] = 0;

            this.types[i] = type;
            this.typeNames[i] = typeInfo.getTypeName(types[i]);
            this.schemas[i] = typeInfo.getSchema(types[i]);

            final String tempTypeName = this.typeNames[i];
        }
        // System.out.println("TYPE: " + typeNames[i]);

        // n[i] = 15;
        // firstLinks[i] = new Hyperlink("First", "First" + i);
        // firstLinks[i].addClickListener(new ClickListener() {
        // public void onClick(Widget sender) {
        // get(type, 0);
        // }
        // });
        // nextLinks[i] = new Hyperlink("Next", "Next" + i);
        // nextLinks[i].addClickListener(new ClickListener() {
        // public void onClick(Widget sender) {
        // int offset = getOffset(type) + getN(type);
        // get(type, offset);
        // }
        // });
        // prevLinks[i] = new Hyperlink("Prev", "Prev" + i);
        // prevLinks[i].addClickListener(new ClickListener() {
        // public void onClick(Widget sender) {
        // int offset = getOffset(type) - getN(type);
        // if (offset < 0)
        // offset = 0;
        // get(type, offset);
        // }
        // });
        // lastLinks[i] = new Hyperlink("Last", "Last" + i);
        // lastLinks[i].addClickListener(new ClickListener() {
        // public void onClick(Widget sender) {
        // int offset = (getRecordCount(type) / getN(type)) * getN(type);
        // get(type, offset);
        // }
        // });
        //
        // deleteLinks[i] = new Hyperlink("Delete", "Delete" + i);
        // deleteLinks[i].addClickListener(new ClickListener() {
        // public void onClick(Widget sender) {
        // MessageBox.show(new MessageBoxConfig() {
        // {
        // setTitle("Delete for " + tempTypeName);
        // setMsg("Enter an SQL delete statement omitting the 'delete':");
        // setWidth(300);
        // setButtons(MessageBox.OKCANCEL);
        // setMultiline(true);
        // setCallback(new MessageBox.PromptCallback() {
        // public void execute(String btnID, String text) {
        // if (btnID.equals("ok"))
        // delete(getQueryID(), type, text);
        // }
        // });
        // }
        // });
        //
        // }
        // });
        //
        // exportLinks[i] = new Hyperlink("Export", "Export" + i);
        // exportLinks[i].addClickListener(new ClickListener() {
        // public void onClick(Widget sender) {
        // String url = "export?queryid=" + getQueryID() + "&type=" + type +
        // "&where="
        // + NetUtil.convertToHex(getWhere(type)) + "&orderby=" +
        // getOrderBy(type);
        // System.out.println(url);
        // Window.open(url, "Export", "");
        // }
        // });
        //
        // // optionDialogs[i] = new BrowseOptionsDialogBox(type, tempTypeName,
        // // getSchema(type));
        // optionDialogs2[i] = new AnalysisOptionsDialog(this, type,
        // tempTypeName, getSchema(type));
        // // optionDialogs[i].addPopupListener(this);
        // where[i] = "";
        // orderBy[i] = "";
        // recordCounts[i] = 0;
        //
        // optionLinks[i] = new Hyperlink("Options", "Options" + i);
        // optionLinks[i].addClickListener(new ClickListener() {
        // public void onClick(Widget sender) {
        // // BrowseOptionsDialogBox popup = optionDialogs[typeIdx];
        // // popup.setPopupPosition(sender.getAbsoluteLeft(),
        // // sender.getAbsoluteTop());
        // // popup.show();
        // optionDialogs2[typeIdx].show();
        // }
        // });
        //
        // statusLabels[i] = new Label();
        // statusLabels[i].setText("Idle");
        //
        // summaryStatusLabels[i] = new Label();
        // summaryStatusLabels[i].setText("Idle");
        //
        // summaryTables[i] = new FlexTable();
        //
        // for (int j = 0; j < summaryTablesByField[i].length; j++) {
        // summaryTablesByField[i][j] = new FlexTable();
        // if (j == NetFSEClient.FIELD_SRC_IP) {
        // summaryDataTables[i].setWidget(0, 0, summaryTablesByField[i][j]);
        // } else if (j == NetFSEClient.FIELD_DST_IP) {
        // summaryDataTables[i].setWidget(0, 1, summaryTablesByField[i][j]);
        // } else if (j == NetFSEClient.FIELD_DST_PORT) {
        // summaryDataTables[i].setWidget(1, 0, summaryTablesByField[i][j]);
        // } else if (j == NetFSEClient.FIELD_PROTOCOL) {
        // summaryDataTables[i].setWidget(1, 1, summaryTablesByField[i][j]);
        // }
        // }
        //
        // }
        //
        // setupBrowseTable(this, types);

    }

    public void sortResultsColumn(FlexRecordGroup frg, int columnIndex, String direction) {
        FlexRecordField frf = frg.flexRecordFields[columnIndex];
        setOrderBy(frg.typeID, frf.columnName + " " + direction);
        getTypeResults(frg.typeID, -1);
    }

    public void testAnalysisPanel() {
        FlexRecordGroup frg = new FlexRecordGroup();
        frg.typeID = 7;
        frg.typeName = "NetFlow";

        String[] columnNames = { "Start Time", "Stop TIme", "Duration", "Src IP", "Src Port", "Src Bytes", "Dst IP",
                "Dst Port", "Dst Bytes", "Protocol", "Service" };
        int[] columnWidth = { 100, 100, 50, 100, 50, 50, 100, 50, 50, 50, 50 };

        int[] columnType = { 4, 4, 1, 4, 1, 1, 4, 1, 1, 1, 4 };

        FlexRecordField[] frf = new FlexRecordField[11];
        for (int y = 0; y < 11; y++) {
            frf[y] = new FlexRecordField();
            frf[y].columnName = columnNames[y];
            frf[y].type = columnType[y];
            frf[y].columnWidth = columnWidth[y];
        }

        frg.records = new FlexRecord[10];

        frg.records[0] = new FlexRecord();
        String[] tempValues0 = { "1999-04-02 02:04:11.135", "", "", "172.16.112.20", "17466", "", "172.16.112.100",
                "25", "", "6", "smtp" };
        frg.records[0].values = tempValues0;

        frg.records[1] = new FlexRecord();
        String[] tempValues1 = { "2000-04-02 02:04:11.135", "", "", "172.16.112.20", "17466", "", "172.16.112.100",
                "25", "", "6", "smtp" };
        frg.records[1].values = tempValues1;

        frg.records[2] = new FlexRecord();
        String[] tempValues2 = { "2001-04-02 02:04:11.135", "", "", "172.16.112.20", "17466", "", "172.16.112.100",
                "25", "", "6", "smtp" };
        frg.records[2].values = tempValues2;

        frg.records[3] = new FlexRecord();
        String[] tempValues3 = { "2003-04-02 02:04:11.135", "", "", "172.16.112.20", "17466", "", "172.16.112.100",
                "25", "", "6", "smtp" };
        frg.records[3].values = tempValues3;

        frg.records[4] = new FlexRecord();
        String[] tempValues4 = { "2004-04-02 02:04:11.135", "", "", "172.16.112.20", "17466", "", "172.16.112.100",
                "25", "", "6", "smtp" };
        frg.records[4].values = tempValues4;

        frg.records[5] = new FlexRecord();
        String[] tempValues5 = { "2005-04-02 02:04:11.135", "", "", "172.16.112.20", "17466", "", "172.16.112.100",
                "25", "", "6", "smtp" };
        frg.records[5].values = tempValues5;

        frg.records[6] = new FlexRecord();
        String[] tempValues6 = { "2006-04-02 02:04:11.135", "", "", "172.16.112.20", "17466", "", "172.16.112.100",
                "25", "", "6", "smtp" };
        frg.records[6].values = tempValues6;

        frg.records[7] = new FlexRecord();
        String[] tempValues7 = { "2007-04-02 02:04:11.135", "", "", "172.16.112.20", "17466", "", "172.16.112.100",
                "25", "", "6", "smtp" };
        frg.records[7].values = tempValues7;

        frg.records[8] = new FlexRecord();
        String[] tempValues8 = { "2008-04-02 02:04:11.135", "", "", "172.16.112.20", "17466", "", "172.16.112.100",
                "25", "", "6", "smtp" };
        frg.records[8].values = tempValues8;

        frg.records[9] = new FlexRecord();
        String[] tempValues9 = { "2009-04-02 02:04:11.135", "", "", "172.16.112.20", "17466", "", "172.16.112.100",
                "25", "", "6", "smtp" };
        frg.records[9].values = tempValues9;

        frg.flexRecordFields = frf;

        buildResultsGridPanel(frg);

        TopValues tv1 = new TopValues();
        tv1.type = 7;
        tv1.stats = new int[10][10];
        tv1.values = new String[10];
        tv1.lows = new String[10];
        tv1.highs = new String[10];
        tv1.totals = new String[10];
        tv1.percents = new String[10];

        tv1.values[0] = "172,16,117,52";
        tv1.lows[0] = "2";
        tv1.highs[0] = "850";
        tv1.totals[0] = "3360";
        tv1.percents[0] = "15.83";

        tv1.values[1] = "172,16,117,52";
        tv1.lows[1] = "2";
        tv1.highs[1] = "850";
        tv1.totals[1] = "3360";
        tv1.percents[1] = "15.83";

        tv1.values[2] = "172,16,117,52";
        tv1.lows[2] = "2";
        tv1.highs[2] = "850";
        tv1.totals[2] = "3360";
        tv1.percents[2] = "15.83";

        tv1.values[3] = "172,16,117,52";
        tv1.lows[3] = "2";
        tv1.highs[3] = "850";
        tv1.totals[3] = "3360";
        tv1.percents[3] = "15.83";

        tv1.values[4] = "172,16,117,52";
        tv1.lows[4] = "2";
        tv1.highs[4] = "850";
        tv1.totals[4] = "3360";
        tv1.percents[4] = "15.83";

        tv1.values[5] = "172,16,117,52";
        tv1.lows[5] = "2";
        tv1.highs[5] = "850";
        tv1.totals[5] = "3360";
        tv1.percents[5] = "15.83";

        tv1.values[6] = "172,16,117,52";
        tv1.lows[6] = "2";
        tv1.highs[6] = "850";
        tv1.totals[6] = "3360";
        tv1.percents[6] = "15.83";

        tv1.values[7] = "172,16,117,52";
        tv1.lows[7] = "2";
        tv1.highs[7] = "850";
        tv1.totals[7] = "3360";
        tv1.percents[7] = "15.83";

        tv1.values[8] = "172,16,117,52";
        tv1.lows[8] = "2";
        tv1.highs[8] = "850";
        tv1.totals[8] = "3360";
        tv1.percents[8] = "15.83";

        tv1.values[9] = "172,16,117,52";
        tv1.lows[9] = "2";
        tv1.highs[9] = "850";
        tv1.totals[9] = "3360";
        tv1.percents[9] = "15.83";

        HashMap summaryPanels = new HashMap();
        summaryPanelMap.put(7 + "", summaryPanels);

        createTypeSummaryPanel(7, NetFSEClient.FIELD_DST_IP, "NewFlow", tv1);
        createTypeSummaryPanel(7, NetFSEClient.FIELD_SRC_IP, "NewFlow", tv1);
        createTypeSummaryPanel(7, NetFSEClient.FIELD_DST_PORT, "NewFlow", tv1);
        createTypeSummaryPanel(7, NetFSEClient.FIELD_PROTOCOL, "NewFlow", tv1);

    }

}
